"""
MiniWeb框架入口程序
"""
import socket
import logging
from multiprocessing import Process
from FrameWork import application


class MiniWebServer(object):
    """Mini Web服务器类"""

    def __init__(self, port):
        """初始化时，创建服务器套接字"""
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        self.server.bind(('', port))
        self.server.listen(128)

    def start(self):
        """服务器启动方法"""
        # 循环监听客户端发来的连接请求
        while True:
            client, ip_port = self.server.accept()
            print(f'客户端{ip_port[0]}使用{ip_port[1]}连接成功')

            # 创建子进程，让子进程完成与客户端的具体数据传输
            p = Process(target=self.task, args=(client,))
            p.start()

            # 关闭主进程与客户端的连接
            client.close()

    def task(self, client):
        request_data = client.recv(1024).decode('utf-8')
        if request_data == 0:
            client.close()
        else:
            # 分割请求报文，获取请求资源的路径
            request_path = request_data.split(' ')[1]
            print(f'请求地址是：{request_path}')
            # 判断是否为根路径，如果是根路径，重新定位到主页
            if request_path == '/':
                request_path = '/index.html'

            # 判断请求资源的类型
            if request_path.endswith('.html'):
                # 处理动态数据
                logging.info(f'客户端请求了一个动态页面，地址是：{request_path}')
                env = {"path": request_path}
                response_body = application(env, self.start_response)
                response_line = 'HTTP/1.1 %s\r\n' % self.__status
                response_head = ''
                for t in self.__headers:
                    response_head += '%s: %s\r\n' % t  # t是元组，会自动拆包

                response_data = (response_line + response_head + '\r\n' + response_body).encode('utf-8')
                client.send(response_data)
                client.close()

            else:
                # 处理静态数据
                try:
                    with open('static' + request_path, 'rb') as file:
                        file_content = file.read()

                # 资源文件未找到，返回404
                except FileNotFoundError:
                    response_line = 'HTTP/1.1 404 NOT FOUND\r\n'
                    response_head = 'Server: PSWS2.0\r\n'
                    with open('templates/error.html', 'r') as f:
                        error_data = f.read()

                    response_data = (response_line + response_head + '\r\n' + error_data).encode('utf-8')
                    client.send(response_data)

                else:
                    response_line = 'HTTP/1.1 200 OK\r\n'
                    response_head = 'Server: PSWS2.0\r\n'
                    response_body = file_content

                    response_data = (response_line + response_head + '\r\n').encode('utf8') + response_body
                    client.send(response_data)

                finally:
                    client.close()

    # 定义一个回调函数，保存状态码和响应头
    def start_response(self, status, headers):
        """"""
        self.__status = status
        self.__headers = headers


# 程序入口
if __name__ == '__main__':
    file_handler = logging.FileHandler(filename='日志.log', encoding='utf-8')
    logging.basicConfig(level=logging.DEBUG,
                        format='%(asctime)s--%(filename)s[%(lineno)d]--%(levelname)s:%(message)s')
    port = 9999
    logging.info(f'服务器处理成功，端口为：{port}')
    MiniWebServer(port).start()

